/**
 * PromptVariableDialog - 提示词变量填写对话框
 * 
 * 功能：
 * 1. 根据模板的变量定义动态生成表单
 * 2. 支持多种变量类型（text, number, select, textarea, boolean）
 * 3. 表单验证
 * 4. 实时预览替换后的提示词
 */

import { useState, useEffect } from 'react';
import { Sparkles, Eye, EyeOff, AlertCircle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { cn } from '@/lib/utils';
import type { PromptTemplate, PromptVariable } from '@/types/prompt';

// ============================================================================
// 类型定义
// ============================================================================

export interface PromptVariableDialogProps {
  /** 选中的模板 */
  template: PromptTemplate;
  /** 确认时的回调 (返回填充后的提示词) */
  onConfirm: (filledPrompt: string, values: Record<string, any>) => void;
  /** 取消时的回调 */
  onCancel: () => void;
  /** 初始变量值 */
  initialValues?: Record<string, any>;
  /** 自定义类名 */
  className?: string;
}

// ============================================================================
// 主组件
// ============================================================================

export function PromptVariableDialog({
  template,
  onConfirm,
  onCancel,
  initialValues = {},
  className,
}: PromptVariableDialogProps) {
  const [values, setValues] = useState<Record<string, any>>(initialValues);
  const [errors, setErrors] = useState<Record<string, string>>({});
  const [showPreview, setShowPreview] = useState(false);

  // 初始化默认值
  useEffect(() => {
    const defaultValues: Record<string, any> = {};
    template.variables.forEach(variable => {
      if (variable.defaultValue !== undefined) {
        defaultValues[variable.name] = variable.defaultValue;
      }
    });
    setValues(prev => ({ ...defaultValues, ...prev }));
  }, [template]);

  // 更新变量值
  const updateValue = (name: string, value: any) => {
    setValues(prev => ({ ...prev, [name]: value }));
    // 清除该字段的错误
    if (errors[name]) {
      setErrors(prev => {
        const newErrors = { ...prev };
        delete newErrors[name];
        return newErrors;
      });
    }
  };

  // 验证表单
  const validate = (): boolean => {
    const newErrors: Record<string, string> = {};
    
    template.variables.forEach(variable => {
      const value = values[variable.name];
      
      // 必填验证
      if (variable.required) {
        if (value === undefined || value === null || value === '') {
          newErrors[variable.name] = `${variable.label} 是必填项`;
          return;
        }
      }
      
      // 类型验证
      if (value !== undefined && value !== null && value !== '') {
        if (variable.type === 'number' && isNaN(Number(value))) {
          newErrors[variable.name] = `${variable.label} 必须是数字`;
        }
      }
    });
    
    setErrors(newErrors);
    return Object.keys(newErrors).length === 0;
  };

  // 生成填充后的提示词
  const generateFilledPrompt = (): string => {
    let result = template.template;
    
    template.variables.forEach(variable => {
      const value = values[variable.name];
      const placeholder = new RegExp(`\\{\\{${variable.name}\\}\\}`, 'g');
      result = result.replace(placeholder, value !== undefined ? String(value) : '');
    });
    
    return result;
  };

  // 确认提交
  const handleConfirm = () => {
    if (validate()) {
      const filledPrompt = generateFilledPrompt();
      onConfirm(filledPrompt, values);
    }
  };

  const hasRequiredFields = template.variables.some(v => v.required);

  return (
    <div className={cn('flex flex-col h-full', className)}>
      {/* 头部 */}
      <div className="p-4 border-b">
        <div className="flex items-start gap-3">
          <div className="flex-1">
            <div className="flex items-center gap-2 mb-1">
              <Sparkles className="h-5 w-5 text-primary" />
              <h3 className="font-semibold">{template.name}</h3>
            </div>
            <p className="text-sm text-muted-foreground">
              {template.description}
            </p>
          </div>
        </div>
      </div>

      {/* 表单区域 */}
      <ScrollArea className="flex-1 p-4">
        <div className="space-y-4">
          {template.variables.map((variable) => (
            <VariableInput
              key={variable.name}
              variable={variable}
              value={values[variable.name]}
              error={errors[variable.name]}
              onChange={(value) => updateValue(variable.name, value)}
            />
          ))}

          {/* 最佳实践提示 */}
          {template.bestPractices && template.bestPractices.length > 0 && (
            <div className="rounded-lg bg-blue-500/10 border border-blue-500/20 p-4">
              <div className="flex items-start gap-2">
                <AlertCircle className="h-4 w-4 text-blue-500 mt-0.5 shrink-0" />
                <div className="flex-1">
                  <h4 className="text-sm font-medium text-blue-500 mb-2">💡 最佳实践</h4>
                  <ul className="text-sm text-muted-foreground space-y-1">
                    {template.bestPractices.map((practice, index) => (
                      <li key={index} className="flex gap-2">
                        <span className="text-blue-500">•</span>
                        <span>{practice}</span>
                      </li>
                    ))}
                  </ul>
                </div>
              </div>
            </div>
          )}

          {/* 示例 */}
          {template.examples && template.examples.length > 0 && (
            <div className="rounded-lg bg-muted/50 p-4">
              <h4 className="text-sm font-medium mb-2">📝 示例</h4>
              <div className="space-y-2">
                {template.examples.map((example, index) => (
                  <p key={index} className="text-sm text-muted-foreground">
                    {example}
                  </p>
                ))}
              </div>
            </div>
          )}
        </div>
      </ScrollArea>

      {/* 预览区域 */}
      {showPreview && (
        <div className="border-t p-4 bg-muted/30 max-h-[200px] overflow-auto">
          <div className="flex items-center gap-2 mb-2">
            <Eye className="h-4 w-4" />
            <h4 className="text-sm font-medium">预览</h4>
          </div>
          <pre className="text-xs whitespace-pre-wrap font-mono text-muted-foreground">
            {generateFilledPrompt()}
          </pre>
        </div>
      )}

      {/* 底部操作栏 */}
      <div className="flex items-center justify-between gap-2 p-4 border-t">
        <Button
          variant="ghost"
          size="sm"
          onClick={() => setShowPreview(!showPreview)}
          className="gap-2"
        >
          {showPreview ? (
            <>
              <EyeOff className="h-4 w-4" />
              隐藏预览
            </>
          ) : (
            <>
              <Eye className="h-4 w-4" />
              显示预览
            </>
          )}
        </Button>

        <div className="flex gap-2">
          <Button variant="ghost" onClick={onCancel}>
            取消
          </Button>
          <Button onClick={handleConfirm}>
            使用模板
            {hasRequiredFields && Object.keys(errors).length > 0 && (
              <Badge variant="destructive" className="ml-2 h-5 px-1.5">
                {Object.keys(errors).length}
              </Badge>
            )}
          </Button>
        </div>
      </div>
    </div>
  );
}

// ============================================================================
// 变量输入组件
// ============================================================================

interface VariableInputProps {
  variable: PromptVariable;
  value: any;
  error?: string;
  onChange: (value: any) => void;
}

function VariableInput({ variable, value, error, onChange }: VariableInputProps) {
  const renderInput = () => {
    switch (variable.type) {
      case 'text':
        return (
          <Input
            value={value || ''}
            onChange={(e) => onChange(e.target.value)}
            placeholder={variable.placeholder}
            className={cn(error && 'border-destructive')}
          />
        );

      case 'number':
        return (
          <Input
            type="number"
            value={value || ''}
            onChange={(e) => onChange(e.target.value)}
            placeholder={variable.placeholder}
            className={cn(error && 'border-destructive')}
          />
        );

      case 'textarea':
        return (
          <textarea
            value={value || ''}
            onChange={(e) => onChange(e.target.value)}
            placeholder={variable.placeholder}
            rows={4}
            className={cn(
              'w-full rounded-md border border-input bg-background px-3 py-2 text-sm',
              'ring-offset-background placeholder:text-muted-foreground',
              'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
              'disabled:cursor-not-allowed disabled:opacity-50 resize-none',
              error && 'border-destructive'
            )}
          />
        );

      case 'select':
        return (
          <select
            value={value || ''}
            onChange={(e) => onChange(e.target.value)}
            className={cn(
              'w-full rounded-md border border-input bg-background px-3 py-2 text-sm',
              'ring-offset-background focus-visible:outline-none focus-visible:ring-2',
              'focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50',
              error && 'border-destructive'
            )}
          >
            <option value="">请选择...</option>
            {variable.options?.map((option) => (
              <option key={option.value} value={option.value}>
                {option.label}
              </option>
            ))}
          </select>
        );

      case 'boolean':
        return (
          <label className="flex items-center gap-2 cursor-pointer">
            <input
              type="checkbox"
              checked={value || false}
              onChange={(e) => onChange(e.target.checked)}
              className="h-4 w-4 rounded border-input"
            />
            <span className="text-sm">{variable.placeholder || '启用'}</span>
          </label>
        );

      default:
        return null;
    }
  };

  return (
    <div className="space-y-2">
      <Label htmlFor={variable.name} className="flex items-center gap-2">
        {variable.label}
        {variable.required && (
          <Badge variant="destructive" className="text-xs h-5">
            必填
          </Badge>
        )}
      </Label>
      
      {variable.description && (
        <p className="text-xs text-muted-foreground">{variable.description}</p>
      )}
      
      {renderInput()}
      
      {error && (
        <p className="text-xs text-destructive flex items-center gap-1">
          <AlertCircle className="h-3 w-3" />
          {error}
        </p>
      )}
    </div>
  );
}

